package com.sk.bilibili.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sk.bilibili.bean.Member;
import com.sk.bilibili.dto.FocusInfo;
import com.sk.bilibili.event.BiliBiliEvent;
import com.sk.bilibili.other.R;
import com.sk.bilibili.utils.BSessionUtils;
import com.sk.bilibili.utils.QueryWrapperUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import com.sk.bilibili.bean.Focus;
import com.sk.bilibili.mapper.FocusMapper;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 邵康
 * @date 2021/11/24 09:26
 */
@Service
public class FocusService extends ServiceImpl<FocusMapper, Focus> {

    @Autowired
    private MemberService memberService;
    @Autowired
    private FocusGroupService focusGroupService;
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public R<Void> add(Focus focus) {
        save(focus);
        return R.success();
    }

    public R<Void> delete(Integer id) {
        removeById(id);
        return R.success();
    }

    public R<Void> update(Focus focus) {
        eventPublisher.publishEvent(new BiliBiliEvent<>(this,focus));
        updateById(focus);
        return R.success();
    }

    public R<IPage<Focus>> page(Integer page, Integer size) {
        return R.success(page(new Page<>(page, size), null));
    }

    public R<Boolean> isFocus(Integer focusId) {
        int memberId = BSessionUtils.getMemberId();
        return R.success(getFocus(memberId, focusId) != null);
    }

    public Focus getFocus(Integer memberId, Integer focusId) {
        QueryWrapper<Focus> queryWrapper = QueryWrapperUtils.eq(
                "follow_id", memberId, "focus_id", focusId);
        return getOne(queryWrapper);
    }

    public R<Focus> switchFocus(Integer focusId) {
        int memberId = BSessionUtils.getMemberId();
        if(focusId==memberId)return R.error("你时刻都在关注你自己");
        Focus focus = getFocus(memberId, focusId);
        Integer focusGroupId;
        if (focus == null) {
            focus = new Focus();
            focus.setFollowId(memberId);
            focus.setFocusId(focusId);
            focus.setFocusGroupId(focusGroupService.getDefaultFocusGroup(memberId));
            save(focus);
            focusGroupId=focus.getFocusGroupId();
        } else {
            focusGroupId=focus.getFocusGroupId();
            removeById(focus.getId());
            focus = null;
        }
        eventPublisher.publishEvent(new BiliBiliEvent<>(this,focus)
                .putExtra("focusGroupId",focusGroupId).putExtra("focusId",focusId));
        return R.success(focus);
    }

    public R<IPage<Member>> focusMember(FocusInfo focusInfo) {
        if (focusInfo.getMemberId() == null) focusInfo.setMemberId(BSessionUtils.getMemberId());
        return R.success(memberService.focusMember(focusInfo.page(), focusInfo));
    }

    public List<Integer> getAllFocus(int memberId) {
        QueryWrapper<Focus> queryWrapper = QueryWrapperUtils.eq("follow_id", memberId);
        queryWrapper.select("focus_id");
        List<Focus> list = list(queryWrapper);
        return list.stream().map(Focus::getFocusId).collect(Collectors.toList());
    }

    public R<List<Member>> followMember(Integer memberId) {
        if (memberId == null) memberId = BSessionUtils.getMemberId();
        return R.success(memberService.followMember(memberId));
    }

    public R<Void> move(Integer[] ids, Integer focusGroupId) {
        for (Integer id : ids) {
            Focus focus = getById(id);
            focus.setFocusGroupId(focusGroupId);
            save(focus);
        }
        return R.success();
    }

    public Integer getFocusNum(Integer id) {
        QueryWrapper<Focus> queryWrapper = QueryWrapperUtils.eq("follow_id", id);
        return count(queryWrapper);
    }

    @EventListener(condition = "event.type == 'com.sk.bilibili.service.FocusGroupService.delete'")
    public void handleFocusGroupDelete(BiliBiliEvent<Integer> event){
        Integer defaultFocusGroup = focusGroupService.getDefaultFocusGroup(BSessionUtils.getMemberId());
        baseMapper.updateGroupId(event.getData(), defaultFocusGroup);
    }

}
